# -*- coding: utf-8 -*-
"""
APScheduler调度器工具
提供全局调度器实例
"""
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.executors.pool import ThreadPoolExecutor
import logging

logger = logging.getLogger(__name__)

# 全局调度器实例
_scheduler = None


def get_scheduler():
    """
    获取全局调度器实例
    如果不存在则创建
    """
    global _scheduler
    
    if _scheduler is None:
        logger.info("初始化APScheduler调度器...")
        
        # 配置执行器
        executors = {
            'default': ThreadPoolExecutor(max_workers=10)
        }
        
        # 配置作业存储（使用内存存储）
        job_defaults = {
            'coalesce': False,  # 是否合并错过的任务
            'max_instances': 1,  # 同一任务的最大并发实例数
            'misfire_grace_time': 60  # 任务错过的宽限时间（秒）
        }
        
        # 创建调度器
        _scheduler = BackgroundScheduler(
            executors=executors,
            job_defaults=job_defaults,
            timezone='Asia/Shanghai'
        )
        
        logger.info("APScheduler调度器初始化完成")
    
    return _scheduler


def start_scheduler():
    """启动调度器"""
    global _scheduler
    
    # 如果调度器不存在，先创建
    if _scheduler is None:
        scheduler = get_scheduler()
    else:
        scheduler = _scheduler
    
    # 启动调度器（如果未运行）
    if not scheduler.running:
        try:
            scheduler.start()
            logger.info("APScheduler调度器已启动")
        except RuntimeError as e:
            # 如果调度器已关闭（shutdown后无法重启），会抛出 RuntimeError
            # 需要重新创建调度器
            if "cannot be started" in str(e).lower() or "shutdown" in str(e).lower():
                logger.warning("调度器已关闭，重新创建...")
                _scheduler = None
                scheduler = get_scheduler()
                scheduler.start()
                logger.info("APScheduler调度器已重新创建并启动")
            else:
                raise
    else:
        logger.info("APScheduler调度器已在运行中")


def shutdown_scheduler(wait=True):
    """
    关闭调度器
    :param wait: 是否等待所有任务完成
    """
    global _scheduler
    
    if _scheduler and _scheduler.running:
        _scheduler.shutdown(wait=wait)
        logger.info("APScheduler调度器已关闭")
        # 不设置为 None，保持实例以便重新启动








